#include "codeprocessor.h"
#include <QFileInfo>
#include <QRegularExpression>
#include <QSet>

const QMap<QString, QStringList> CodeProcessor::languageExtensions = {
    {"C++", {".cpp", ".h", ".hpp", ".cc"}},
    {"Java", {".java"}},
    {"Python", {".py"}},
    {"JavaScript", {".js"}},
    {"Go", {".go"}},
    {"PHP", {".php"}},
    {"Ruby", {".rb"}},
    {"HTML", {".html", ".htm"}},
    {"CSS", {".css"}}
};

bool CodeProcessor::isSourceFile(const QString &filePath, const QStringList &languages)
{
    if (languages.isEmpty() || languages.contains("全部")) {
        return true;
    }
    
    QFileInfo fileInfo(filePath);
    QString suffix = "." + fileInfo.suffix().toLower();
    
    // 收集所有选中语言的扩展名
    QSet<QString> validExtensions;
    for (const QString &lang : languages) {
        validExtensions.unite(QSet<QString>::fromList(languageExtensions[lang]));
    }
    
    return validExtensions.contains(suffix);
}

QString CodeProcessor::removeCommentsAndEmptyLines(const QString &sourceCode, const QString &language)
{
    QString processed;
    if (language == "C++" || language == "Java" || language == "JavaScript" || language == "CSS") {
        processed = removeCppStyleComments(sourceCode);
    } else if (language == "Python" || language == "Ruby") {
        processed = removePythonStyleComments(sourceCode);
    } else if (language == "HTML") {
        processed = removeHtmlStyleComments(sourceCode);
    } else {
        processed = sourceCode;
    }
    
    // 移除空行并保持缩进
    QStringList lines = processed.split('\n');
    QStringList nonEmptyLines;
    for (const QString &line : lines) {
        QString trimmed = line.trimmed();
        if (!trimmed.isEmpty()) {
            nonEmptyLines.append(line);
        }
    }
    
    return nonEmptyLines.join("\n");
}

QString CodeProcessor::removeCppStyleComments(const QString &sourceCode)
{
    QString result = sourceCode;
    
    // 移除多行注释 /* ... */
    QRegularExpression multiComment(R"(/\*[\s\S]*?\*/)");
    result.remove(multiComment);
    
    // 移除单行注释 //
    QRegularExpression singleComment(R"(//[^\n]*)");
    result.remove(singleComment);
    
    return result;
}

QString CodeProcessor::removePythonStyleComments(const QString &sourceCode)
{
    QStringList lines = sourceCode.split("\n");
    QStringList processedLines;
    bool inMultilineComment = false;
    
    for (const QString &line : lines) {
        QString trimmedLine = line.trimmed();
        
        // 处理多行注释
        if (trimmedLine.startsWith("'''") || trimmedLine.startsWith("\"\"\"")) {
            inMultilineComment = !inMultilineComment;
            continue;
        }
        
        if (!inMultilineComment && !trimmedLine.startsWith("#")) {
            processedLines.append(line);
        }
    }
    
    return processedLines.join("\n");
}

QString CodeProcessor::removeHtmlStyleComments(const QString &sourceCode)
{
    QString result = sourceCode;
    QRegularExpression htmlComment(R"(<!--[\s\S]*?-->)");
    result.remove(htmlComment);
    return result;
}

QStringList CodeProcessor::splitToPages(const QString &code, int linesPerPage)
{
    QStringList pages;
    QStringList allLines = code.split('\n');
    
    // 计算需要多少页
    int totalPages = (allLines.size() + linesPerPage - 1) / linesPerPage;
    
    for (int i = 0; i < totalPages; ++i) {
        QStringList pageLines;
        
        // 获取当前页的行
        int startLine = i * linesPerPage;
        int endLine = qMin(startLine + linesPerPage, allLines.size());
        
        // 添加实际的代码行
        for (int j = startLine; j < endLine; ++j) {
            pageLines.append(allLines[j]);
        }
        
        // 如果不足50行，补充空行
        while (pageLines.size() < linesPerPage) {
            pageLines.append(" "); // 使用空格而不是空字符串，确保行号显示
        }
        
        pages.append(pageLines.join('\n'));
    }
    
    return pages;
}

QStringList CodeProcessor::getSupportedLanguages()
{
    return languageExtensions.keys();
}

QStringList CodeProcessor::getExtensionsForLanguage(const QString &language)
{
    return languageExtensions.value(language);
}

QString CodeProcessor::getLanguageByExtension(const QString &filePath)
{
    QFileInfo fileInfo(filePath);
    QString suffix = "." + fileInfo.suffix().toLower();
    
    for (auto it = languageExtensions.begin(); it != languageExtensions.end(); ++it) {
        if (it.value().contains(suffix)) {
            return it.key();
        }
    }
    
    return QString(); // 如果没找到匹配的语言，返回空字符串
} 